package walkera.cn.http;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;


import androidx.annotation.NonNull;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class HttpClient {
    private static String token = "";
    private static Retrofit retrofit;
    /**一个主地址 对应一个client */
    private static HashMap<String, HttpClient> clients = new HashMap<>();

    private HttpClient(String baseUrl ,Context context) {
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl) // 设置接口主地址
                .client(getHttpRequestClient(context))  // 配置 HTTP 请求客户端
                .addConverterFactory(GsonConverterFactory.create()) // 配置json 转换器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 添加支持 - 返回值定义为Observable对象
                .build();
    }


    public   <T> T createApi(Class<T> clazz) {
        return retrofit==null? null : retrofit.create(clazz);
    }

    public static HttpClient getInstance(String baseUrl ,Context context){
        if(!clients.containsKey(baseUrl))   {
            HttpClient httpClient = new HttpClient(baseUrl ,context);
            clients.put(baseUrl, httpClient);
        }
        return clients.get(baseUrl);
    }



    private OkHttpClient getHttpRequestClient(final Context context) {
        // 拦截器
        Interceptor interceptor = new Interceptor() {
            @NonNull
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request()
                        .newBuilder()
                        .addHeader("token", token)
                        .build();

                // 无网络时 ，使用缓存
                if (! isNetworkConnected( context )) {
                    request = request.newBuilder()
                            .cacheControl(CacheControl.FORCE_CACHE)
                            .build();
                }

                Response response = chain.proceed(request);
                if ( isNetworkConnected( context )) {
                    // 有网络时 设置缓存超时时间0个小时
                    int maxAge = 0; //0 * 60
                    response.newBuilder()
                            .addHeader("Cache-Control", "public, max-age=" + maxAge)
                            // 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                            .removeHeader("Pragma")
                            .build();
                } else {
                    // 无网络时，设置超时为1周
                    int maxStale = 60 * 60 * 24 * 7;
                    response.newBuilder()
                            .addHeader("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                            .removeHeader("Pragma")
                            .build();
                }
                return response;
            }

        };

        // 日志打印
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(myLog );
        logging.setLevel(HttpLoggingInterceptor.Level.BODY); //BODY NONE

        // 缓存
        String cacheDir = context.getExternalCacheDir().getAbsolutePath() ;
        File httpCacheDirectory = new File(cacheDir , "OKHttpResponses");
        Cache cache = new Cache(httpCacheDirectory, 50 * 1024 * 1024);

        return new OkHttpClient.Builder()
                .addInterceptor(logging)
                .cache(cache)
                .addInterceptor(interceptor)
                .build();
    }

    private  boolean isNetworkConnected(Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (manager == null) {
            return false;
        }
        NetworkInfo info = manager.getActiveNetworkInfo();
        if (info == null) {
            return false;
        }
        return info.isConnected();
    }

    private HttpLoggingInterceptor.Logger myLog= new HttpLoggingInterceptor.Logger(){
        @Override
        public void log(@NonNull String message) {
            Log.d("\n\nhttp日志打印------>\r\n: ", message);
        }
    };


}
